ГПОУ ТО "ДКИТ"

Программирование протокола NetBIOS

Функция Netbios предоставляет доступ к системам управления протоколом NetBIOS.

UCHAR Netbios(

PNCB pncb

);

pncb - указатель на структуру NCB, которая описывает сетевые контрольные блоки.

Функция возвращает значение ncb_retcode, находящееся в структуре NCB.

Структура NCB содержит информацию о командах, опциях и указателях на блоки памяти.

typedef struct _NCB {

UCHAR ncb_command ;

UCHAR ncb_retcode;

UCHAR ncb_lsn;

UCHAR ncb_num;

PUCHAR ncb_buffer;

WORD ncb_length;

UCHAR ncb_callname[NCBNAMSZ]/

UCHAR ncb_name [NCBNAMSZ] ;

UCHAR ncb_rto;

UCHAR ncb_sto;

void (CALLBACK *ncb_joost) (struct _NCB *);

UCHAR ncb_lana_num;

UCHAR ncb_cmd_cplt;

#ifdef _WIN64

UCHAR ncb_reserve[18];

#else

UCHAR ncb_reserve[10]; #endif

HANDLE ncb_event;

} NCB, *PNCB;

ncb_command - команда для выполнения функцией Netbios. ncb_retcode - возвращает результат после выполнения операции.

ncb_lsn - идентификатор номера сессии после удачного выполнения команды NCBCALL

ncbjnum - содержит номер локального имени после удачного выполнения команды NCBADDNAME. Применяется для всех команд, использующих дейтаграммы.

ncbjbuffer - указатель на буфер памяти.

ncb_length - размер буфера, в байтах.

ncb_callname - имя удаленного приложения.

ncbjname - имя, которое использует приложение для связи.

ncb_rto - тайм-аут для операции приема пакетов NCBRECV.

ncb_sto - тайм-аут для операции отсылки пакетов NCBSEND.

ncb_post - содержит адрес сообщения для вызова асинхронных команд.

ncb_lana_num - содержит номер LAN адаптера. ncb_cmd_cplt - то же, что и ncb_retcode. ncb_reserve - зарезервировано. Должно быть нулем. ncb_event - содержит хендл объекта сообщения.

4.2.3. Использование протокола

В начале программы необходимо подготовить приложение к работе, используя команду NCBRESET с параметрами количества имен и сессий. Затем добавить новое имя в список локальных имен командой NCBADDNAME.

Если мы используем логический канал, то необходимо использовать команду NCBLISTEN для ожидания входящих подключений для сервера, а для клиента мы используем команду NCBCALL для подключения. После установки соединения по логическому каналу мы можем использовать команду NCBSEND для отсылки сообщений и команду NCBRECV для их приема. Для разрыва канала необходимо воспользоваться командой NCBHANGUP для сервера или клиента.

Если пользуемся дейтаграммами, то сразу для сервера используем команду приема сообщений NCBDGRECV, а для клиента команду передачи сообщения NCBDGSEND.

Для удаления неиспользуемого имени из списка возьмем команду NCBDELNAME, а для вывода списка имен команду NCBASTAT. LAN- адаптеры можно посмотреть с помощью команды NCBENUM.

Сервер использует LAN-адаптер с номером 0 и локальное имя “NewServer”. Ожидает подключения клиента с любым именем, принимает от него пакеты размером 512 байт. После каждого принятого пакета отсылает клиенту строку “ОК!!!”. После выхода из приложения все имена текущего приложения автоматически удаляются из списка локальных имен. В данном примере рассмотрен сервер, использующий логический канал.

//--------------------------------------------------

#include

#include

#include

#pragma hdrstop

//--------------------------------------------------

#pragma argsused int main()

{

NCB f^ncb;

int Netbios_Lana=0;

memset(&f_ncb, 0, sizeof(NCB)); f^ncb.ncb_command=NCBRESET; f^ncb.ncb_lsn=0; f_ncb.ncb_callname[0]=20; f^ncb.ncb_callname[2]=30; f _ncb.ncb_lana_num=Netbios_Lana;

Netbios(&f_ncb);

if(f_ncb.ncb_retcode!=0) return 0;

memset(&f_ncb, 0, sizeof(NCB)); f_ncb.ncb_command=NCBADDNAME; memset(f_ncb.ncb_name, 0, NCBNAMSZ); strcpy(f_ncb.ncb_name, "NewServer"); f_ncb.ncb_lana_num=Netbios_Lana;

Netbios(&f_ncb);

if(f_ncb.ncb_retcode!=0) return 0;

int F_Session=-l;

while(1)

{

memset(&f_ncb, 0, sizeof(NCB)); f_ncb.ncb_command=NCBLISTEN; memset(f_ncb.ncb_callname, 0, NCBNAMSZ); strcpy(f_ncb.ncb_callname, "*"); memset(f_ncb.ncb_name, 0, NCBNAMSZ); strcpy(f_ncb.ncb_name, "NewServer"); f_ncb.ncb_lana_num=Netbios_Lana;

Netbios(&f_ncb);

if(f^ncb.ncb_retcode!=0) return 0; F_Session=f_ncb.ncb_lsn;

unsigned char Data[512];

while(1)

{

memset(&f_ncb, 0, sizeof(NCB));

f_ncb.ncb_command=NCBRECV;

f_ncb.ncb_lsn=F_Session;

f^ncb.ncb_buffer=Data;

f_ncb.ncb_length=512;

f^ncb.ncb_lana_num=Netbios_Lana;

Netbios(&f_ncb);

if(f_ncb.ncb_retcode!=0) break;

puts(Data);

memset(&f_ncb, 0, sizeof(NCB)); f^ncb.ncb_command=NCBSEND; f^ncb.ncb_lsn=F_Session;

f_ncb.ncb_buffer=(unsigned char*)"OK!!!";

f_ncb.ncb_length=6;

f^ncb.ncb_lana_num=Netbios_Lana;

Netbios(&f_ncb);

}

}

return 0;

}

//--------------------------------------------------

4.2.4.2. Пример фрагмента программы клиента с протоколом NetBIOS

Клиент использует LAN- адаптер 0 и локальное имя “NewClient”. Соединяется с сервером по логическому каналу и передает введенные строки, затем получает от сервера строку “ОК!!!”. Также после выхода все локальные имена приложения удаляются.

//-------------------------------------------------#include #include #include #pragma hdrstop

//------------------

#pragma argsused int main()

{

NCB f^ncb;

int Netbios_Lana=0;

memset(&f_ncb, 0, sizeof(NCB)); f^ncb.ncb_command=NCBRESET; f_ncb.ncb_lsn=0; f_ncb.ncb_callname[0]=20; f^ncb.ncb_callname[2]=30; f_ncb.ncb_lana_num=Netbios_Lana;

Netbios(&f_ncb);

if(f_ncb.ncb_retcode!=0) return 0;

memset. (&f_ncb, 0, sizeof (NCB) ) ; f_ncb.ncb_command=NCBADDNAME; memset(f_ncb.ncb_name, 0, NCBNAMSZ); strcpy(f_ncb.ncb_name, "NewClient"); f_ncb.ncb_lana_num=Netbios_Lana;

Netbios(&f_ncb);

if(f_ncb.ncb_retcode!=0) return 0;

int F_Session=-l ;

memset(&f_ncb, 0, sizeof(NCB));

f_ncb.ncb_command=NCBCALL;

memset(f_ncb.ncb_callname, 0, NCBNAMSZ);

strcpy(f_ncb.ncb_callname, "NewServer");

memset(f_ncb.ncb_name, 0, NCBNAMSZ); strcpy(f_ncb.ncb_name, "NewClient"); f_ncb.ncb_lana_num=Netbios_Lana; Netbios(&f_ncb);

if(f_ncb.ncb_retcode!=0) return 0; F_Session=f_ncb.ncb_lsn;

unsigned char Data[512];

while (1)

{

gets(Data);

memset(Sf^ncb, 0, sizeof(NCB)); f_ncb.ncb_command=NCBSEND; f_ncb.ncb_lsn=F_Session; f_ncb.ncb_buffer=Data; f_ncb.ncb_length=strlen(Data)+1; f_ncb.ncb_lana_num=Netbios_Lana; Netbios(&f_ncb);

memset(&f_ncb, 0, sizeof(NCB)); f_ncb.ncb_command=NCBRECV; f_ncb.ncb_lsn=F_Session; f_ncb.ncb_buffer=Data; f_ncb.ncb_length=512; f_ncb.ncb_lana_num=Netbios_Lana; Netbios(&f_ncb); if(f_ncb.ncb_retcode!=0) break;

puts(Data);

}

return 0;

}

//-------------------------------------

4.2.4.3. Комментарии к примерам

Для построения приложения с дейтаграммами не нужно использовать команды прослушивания и вызова, достаточно просто начать прием дейтаграмм или их передачу. Также используются номера имен, а не их значения.

Примеры написаны на Borland Developer Studio 2012. Для подробной справки используйте справочную систему вашего компилятора.